<template>
  <div class="iform-table-container">
    <el-table :data="tableData" :columns="columns" :border="attrs.border" :stripe="attrs.stripe" :size="attrs.size"
      :height="attrs.height" :max-height="attrs.maxHeight" :show-header="attrs.showHeader"
      :highlight-current-row="attrs.highlightCurrentRow" :row-key="attrs.rowKey" :empty-text="attrs.emptyText"
      :show-summary="attrs.showSummary" :sum-text="attrs.sumText" :summary-method="attrs.summaryMethod"
      :span-method="spanMethod" :style="computedStyle" :class="attrs.tableClass"
      :header-cell-style="attrs.headerCellStyle" :cell-style="attrs.cellStyle" @select="handleSelect"
      @select-all="handleSelectAll" @selection-change="handleSelectionChange" @row-click="handleRowClick"
      @row-dblclick="handleRowDblclick" @row-contextmenu="handleRowContextmenu" @sort-change="handleSortChange"
      @filter-change="handleFilterChange" @current-change="handleCurrentChange" @header-dragend="handleHeaderDragend"
      @expand-change="handleExpandChange">
      <el-table-column v-for="column in computedColumns" :key="column.prop" :prop="column.prop" :label="column.label"
        :width="column.width" :min-width="column.minWidth" :fixed="column.fixed" :sortable="column.sortable"
        :sort-by="column.sortBy" :sort-orders="column.sortOrders" :filters="column.filters"
        :filter-method="column.filterMethod" :filter-multiple="column.filterMultiple" :column-key="column.columnKey"
        :formatter="column.formatter" :show-overflow-tooltip="column.showOverflowTooltip" :align="column.align"
        :header-align="column.headerAlign" :class-name="column.className" :label-class-name="column.labelClassName"
        :selectable="column.selectable" :reserve-selection="column.reserveSelection" :type="column.type">
        <template #default="scope">
          <span v-if="column.slot">
            <slot :name="column.slot" :row="scope.row" :column="scope.column" :index="scope.$index" />
          </span>
          <span v-else>
            <span v-if="hasHtmlContent(getCellContent(scope.row[column.prop]))"
              v-html="getCellContent(scope.row[column.prop])"></span>
            <span v-else>{{ getCellContent(scope.row[column.prop]) }}</span>
          </span>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页组件 -->
    <el-pagination v-if="attrs.pagination" v-model:current-page="currentPage" v-model:page-size="pageSize"
      :page-sizes="[10, 20, 50, 100]" :total="attrs.total || tableData.length"
      layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
      @current-change="handlePageChange" />
  </div>
</template>

<script setup lang="ts" name="IFormTableComponent">
import { computed, ref, watch } from 'vue'
import Desc from './index'

interface TableColumn {
  prop: string
  label: string
  width?: number | string
  minWidth?: number | string
  fixed?: boolean | 'left' | 'right'
  sortable?: boolean | 'custom'
  sortBy?: string | string[]
  sortOrders?: string[]
  filters?: Array<{ text: string; value: any }>
  filterMethod?: (value: any, row: any, column: any) => boolean
  filterMultiple?: boolean
  columnKey?: string
  formatter?: (row: any, column: any, cellValue: any, index: number) => string
  showOverflowTooltip?: boolean
  align?: 'left' | 'center' | 'right'
  headerAlign?: 'left' | 'center' | 'right'
  className?: string
  labelClassName?: string
  selectable?: (row: any, index: number) => boolean
  reserveSelection?: boolean
  type?: 'selection' | 'index' | 'expand'
  slot?: string
}

interface Props {
  value?: any[]
  attrs?: Record<string, unknown>
  style?: Record<string, unknown>
  columns?: TableColumn[]
}

const props = withDefaults(defineProps<Props>(), {
  value: () => [],
  attrs: () => Desc.attrs,
  style: () => Desc.style,
  columns: () => []
})

const computedStyle = computed(() => {
  return {
    ...props.style,
    width: props.style?.width + 'px',
    height: props.style?.height + 'px'
  }
})

const emit = defineEmits<{
  'update:value': [value: any[]]
  'select': [selection: any[], row: any]
  'select-all': [selection: any[]]
  'selection-change': [selection: any[]]
  'row-click': [row: any, column: any, event: Event]
  'row-dblclick': [row: any, column: any, event: Event]
  'row-contextmenu': [row: any, column: any, event: Event]
  'sort-change': [sortInfo: { column: any; prop: string; order: string }]
  'filter-change': [filters: Record<string, any[]>]
  'current-change': [currentRow: any, oldCurrentRow: any]
  'header-dragend': [newWidth: number, oldWidth: number, column: any, event: Event]
  'expand-change': [row: any, expandedRows: any[]]
  'page-change': [page: number]
  'size-change': [size: number]
}>()

// 表格数据
const tableData = ref(props.value || props.attrs.tableData as any[] || [])

// 分页相关
const currentPage = ref(props.attrs.currentPage as number || 1)
const pageSize = ref(props.attrs.pageSize as number || 10)

// 计算列配置
const computedColumns = computed((): TableColumn[] => {
  // 优先使用props.columns
  if (props.columns && props.columns.length > 0) {
    return props.columns
  }

  // 其次尝试从attrs.columns中获取（用于Word导入的表格）
  if (props.attrs.columns && Array.isArray(props.attrs.columns) && props.attrs.columns.length > 0) {
    return props.attrs.columns as TableColumn[]
  }

  // 如果没有提供列配置，尝试从数据中生成
  if (tableData.value.length > 0) {
    const firstRow = tableData.value[0]
    return Object.keys(firstRow).map(key => ({
      prop: key,
      label: key,
      width: undefined,
      sortable: false,
      showOverflowTooltip: true,
      align: 'left' as const
    }))
  }

  // 默认列配置
  return [
    { prop: 'name', label: '名称', width: 120, sortable: false, showOverflowTooltip: true, align: 'left' as const },
    { prop: 'value', label: '值', width: 200, sortable: false, showOverflowTooltip: true, align: 'left' as const },
    { prop: 'description', label: '描述', width: 300, sortable: false, showOverflowTooltip: true, align: 'left' as const }
  ]
})

// 监听外部数据变化
watch(() => props.value, (newValue) => {
  tableData.value = newValue || []
})

watch(() => props.attrs.tableData, (newValue) => {
  tableData.value = newValue as any[] || []
})

// 监听内部数据变化
watch(tableData, (newValue) => {
  emit('update:value', newValue)
})

// 事件处理函数
const handleSelect = (selection: any[], row: any) => {
  emit('select', selection, row)
  if (props.attrs.onSelect && typeof props.attrs.onSelect === 'function') {
    (props.attrs.onSelect as (selection: any[], row: any) => void)(selection, row)
  }
}

const handleSelectAll = (selection: any[]) => {
  emit('select-all', selection)
  if (props.attrs.onSelectAll && typeof props.attrs.onSelectAll === 'function') {
    (props.attrs.onSelectAll as (selection: any[]) => void)(selection)
  }
}

const handleSelectionChange = (selection: any[]) => {
  emit('selection-change', selection)
  if (props.attrs.onSelectionChange && typeof props.attrs.onSelectionChange === 'function') {
    (props.attrs.onSelectionChange as (selection: any[]) => void)(selection)
  }
}

const handleRowClick = (row: any, column: any, event: Event) => {
  emit('row-click', row, column, event)
  if (props.attrs.onRowClick && typeof props.attrs.onRowClick === 'function') {
    (props.attrs.onRowClick as (row: any, column: any, event: Event) => void)(row, column, event)
  }
}

const handleRowDblclick = (row: any, column: any, event: Event) => {
  emit('row-dblclick', row, column, event)
  if (props.attrs.onRowDblclick && typeof props.attrs.onRowDblclick === 'function') {
    (props.attrs.onRowDblclick as (row: any, column: any, event: Event) => void)(row, column, event)
  }
}

const handleRowContextmenu = (row: any, column: any, event: Event) => {
  emit('row-contextmenu', row, column, event)
  if (props.attrs.onRowContextmenu && typeof props.attrs.onRowContextmenu === 'function') {
    (props.attrs.onRowContextmenu as (row: any, column: any, event: Event) => void)(row, column, event)
  }
}

const handleSortChange = (sortInfo: { column: any; prop: string; order: string }) => {
  emit('sort-change', sortInfo)
  if (props.attrs.onSortChange && typeof props.attrs.onSortChange === 'function') {
    (props.attrs.onSortChange as (sortInfo: { column: any; prop: string; order: string }) => void)(sortInfo)
  }
}

const handleFilterChange = (filters: Record<string, any[]>) => {
  emit('filter-change', filters)
  if (props.attrs.onFilterChange && typeof props.attrs.onFilterChange === 'function') {
    (props.attrs.onFilterChange as (filters: Record<string, any[]>) => void)(filters)
  }
}

const handleCurrentChange = (currentRow: any, oldCurrentRow: any) => {
  emit('current-change', currentRow, oldCurrentRow)
  if (props.attrs.onCurrentChange && typeof props.attrs.onCurrentChange === 'function') {
    (props.attrs.onCurrentChange as (currentRow: any, oldCurrentRow: any) => void)(currentRow, oldCurrentRow)
  }
}

const handleHeaderDragend = (newWidth: number, oldWidth: number, column: any, event: Event) => {
  emit('header-dragend', newWidth, oldWidth, column, event)
  if (props.attrs.onHeaderDragend && typeof props.attrs.onHeaderDragend === 'function') {
    (props.attrs.onHeaderDragend as (newWidth: number, oldWidth: number, column: any, event: Event) => void)(newWidth, oldWidth, column, event)
  }
}

const handleExpandChange = (row: any, expandedRows: any[]) => {
  emit('expand-change', row, expandedRows)
  if (props.attrs.onExpandChange && typeof props.attrs.onExpandChange === 'function') {
    (props.attrs.onExpandChange as (row: any, expandedRows: any[]) => void)(row, expandedRows)
  }
}

const handlePageChange = (page: number) => {
  currentPage.value = page
  emit('page-change', page)
}

const handleSizeChange = (size: number) => {
  pageSize.value = size
  emit('size-change', size)
}

// 获取单元格内容
const getCellContent = (cellData: any) => {
  // 如果是合并单元格对象，返回content
  if (cellData && typeof cellData === 'object' && cellData.content !== undefined) {
    return cellData.content
  }
  // 否则直接返回数据
  return cellData
}

// 判断内容是否包含HTML标签
const hasHtmlContent = (content: any) => {
  if (!content || typeof content !== 'string') {
    return false
  }

  // 检测HTML标签的正则表达式
  const htmlTagRegex = /<[^>]+>/i

  // 检测常见的HTML标签
  const commonHtmlTags = [
    '<br', '<b>', '</b>', '<i>', '</i>', '<u>', '</u>',
    '<strong>', '</strong>', '<em>', '</em>', '<span',
    '<div', '<p>', '</p>', '<a ', '</a>', '<img',
    '<table', '</table>', '<tr', '</tr>', '<td', '</td>',
    '<th', '</th>', '<ul', '</ul>', '<ol', '</ol>',
    '<li', '</li>', '<h1', '</h1>', '<h2', '</h2>',
    '<h3', '</h3>', '<h4', '</h4>', '<h5', '</h5>', '<h6', '</h6>'
  ]

  // 检查是否包含HTML标签
  if (htmlTagRegex.test(content)) {
    return true
  }

  // 检查是否包含常见的HTML标签
  return commonHtmlTags.some(tag => content.includes(tag))
}

// 默认合并单元格方法
const defaultSpanMethod = ({ row, column }: any) => {
  // 如果行数据中包含合并信息
  if (row && typeof row === 'object') {
    const cellData = row[column.property]

    // 检查是否是合并单元格数据
    if (cellData && typeof cellData === 'object' && (cellData.rowspan || cellData.colspan)) {
      const rowspan = cellData.rowspan || 1
      const colspan = cellData.colspan || 1

      // 返回合并配置 [rowspan, colspan]
      return [rowspan, colspan]
    }
  }

  // 默认不合并
  return [1, 1]
}

// 合并单元格方法 - 优先使用外部传入的，否则使用默认的
const spanMethod = computed(() => {
  return props.attrs.spanMethod || defaultSpanMethod
})

// 暴露方法给父组件
defineExpose({
  tableData,
  currentPage,
  pageSize,
  computedColumns,
  spanMethod,
  defaultSpanMethod,
  getCellContent,
  hasHtmlContent
})
</script>

<style scoped lang="scss">
.iform-table-container {
  width: 100%;

  .el-table {
    width: 100%;
  }

  .el-pagination {
    margin-top: 16px;
    text-align: right;
  }
}
</style>
